package com.runfast.common.web.controller;

import com.runfast.common.exception.BaseException;
import com.runfast.common.utils.LogUtils;
import com.runfast.common.web.entity.Result;
import com.runfast.common.web.entity.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.validation.BindException;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.async.WebAsyncUtils;
import org.springframework.web.util.ContentCachingRequestWrapper;

import javax.servlet.http.HttpServletRequest;

@ControllerAdvice
@Slf4j
public class ExceptionController {


    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Result defaultErrorHandler(HttpServletRequest request, Exception e) throws Exception {
        ;
        boolean isFirstRequest = !WebAsyncUtils.getAsyncManager(request).hasConcurrentResult();
        HttpServletRequest requestToUse = request;

        if (isFirstRequest && !(request instanceof ContentCachingRequestWrapper)) {
            requestToUse = new ContentCachingRequestWrapper(request);
        }
        if (isFirstRequest) LogUtils.loggingRequest(requestToUse);
        if (e instanceof BaseException) {
            BaseException baseException = (BaseException) e;
            return Result.fail(baseException.getErrorCode(), baseException.getMessage());
        } else if (e instanceof IllegalArgumentException || e instanceof BindException || e instanceof ServletRequestBindingException) {
            log.error("", e);
            return Result.fail(ResultCode.PARAMETER_ERROR, ExceptionUtils.getRootCauseMessage(e));
        } else {
            log.error("", e);
            return Result.fail(ResultCode.SYSTEM_BUSY, e.toString());
        }

    }

}
